package qwq.zyu.spigotPluginTianguo;

import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Display;
import org.bukkit.entity.Entity;
import org.bukkit.entity.TextDisplay;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Transformation;
import org.joml.AxisAngle4f;
import org.joml.Vector3f;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class VideoPlayer {
    private final SpigotPluginTianguo plugin;
    private boolean isPlaying = false;
    private final List<List<Color>> frames = new ArrayList<>();
    private final List<UUID> textDisplayUUIDs = new ArrayList<>();
    private BukkitRunnable videoTask;
    private int frameIndex = 0;
    
    // 存储实际的视频尺寸
    private int actualFrameWidth = 0;
    private int actualFrameHeight = 0;

    public VideoPlayer(SpigotPluginTianguo plugin) {
        this.plugin = plugin;
    }

    public boolean loadFrames() {
        frames.clear();
        try (InputStream inputStream = plugin.getResource("video.bin")) {
            if (inputStream == null) {
                plugin.getLogger().severe("video.bin not found in resources!");
                return false;
            }
            byte[] allBytes = inputStream.readAllBytes();
            ByteBuffer buffer = ByteBuffer.wrap(allBytes);

            // 读取头部信息（前12字节）
            int binFileWidth = buffer.getInt();      // 4字节：宽度
            int binFileHeight = buffer.getInt();     // 4字节：高度  
            int totalFrames = buffer.getInt();       // 4字节：总帧数
            
            plugin.getLogger().info("读取到 bin 文件信息 - 宽度: " + binFileWidth + ", 高度: " + binFileHeight + ", 总帧数: " + totalFrames);
            
            // 使用 bin 文件中的实际尺寸（新格式：80x45分辨率，3600个实体）
            int frameWidth = binFileWidth;
            int frameHeight = binFileHeight;
            
            // 保存实际尺寸供后续使用
            this.actualFrameWidth = frameWidth;
            this.actualFrameHeight = frameHeight;
            
            int pixelLength = 6; // RGB hex string
            int frameSize = frameWidth * frameHeight * pixelLength;

            while (buffer.hasRemaining()) {
                if (buffer.remaining() < frameSize) {
                    break;
                }
                byte[] frameData = new byte[frameSize];
                buffer.get(frameData);
                List<Color> frame = new ArrayList<>();
                for (int y = 0; y < frameHeight; y++) {
                    StringBuilder line = new StringBuilder();
                    for (int x = 0; x < frameWidth; x++) {
                        int offset = (y * frameWidth + x) * pixelLength;
                        String hexColor = new String(frameData, offset, pixelLength, StandardCharsets.UTF_8);
                        // 将RGB hex转换为ARGB颜色
                        int argbColor = 0xFF000000 | Integer.parseInt(hexColor, 16);
                        frame.add(Color.fromARGB(argbColor));
                    }
                }
                frames.add(frame);
            }
            plugin.getLogger().info("Loaded " + frames.size() + " frames.");
            return true;
        } catch (Exception e) {
            plugin.getLogger().severe("Error loading frames: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    public void play(Location location, double customPixelSize) {
        if (isPlaying) {
            return;
        }
        if (frames.isEmpty()) {
            plugin.getLogger().warning("No frames loaded, cannot play video.");
            return;
        }

        isPlaying = true;
        frameIndex = 0;
        createTextDisplayEntities(location, customPixelSize);

        videoTask = new BukkitRunnable() {
            @Override
            public void run() {
                if (frameIndex >= frames.size()) {
                    stop();
                    return;
                }
                renderFrame(frameIndex);
                frameIndex++;
            }
        };
        videoTask.runTaskTimer(plugin, 0, 1);
    }

    public void play(Location location) {
        play(location, plugin.getPixelSize());
    }

    public void stop() {
        if (!isPlaying) {
            return;
        }
        isPlaying = false;
        if (videoTask != null) {
            videoTask.cancel();
            videoTask = null;
        }
        removeTextDisplayEntities();
    }

    private void createTextDisplayEntities(Location startLocation, double customPixelSize) {
        removeTextDisplayEntities();
        World world = startLocation.getWorld();
        if (world == null) return;

        // 使用实际的视频尺寸
        int frameWidth = this.actualFrameWidth;
        int frameHeight = this.actualFrameHeight;
        
        // 使用传入的像素大小参数
        double pixelSize = customPixelSize;

        // 为每个像素创建一个 TextDisplay 实体
        for (int y = 0; y < frameHeight; y++) {
            for (int x = 0; x < frameWidth; x++) {
                // 计算像素位置相对于基准位置的偏移量（与BadApple保持一致）
                double adjustedX = (x - frameWidth / 2.0) * pixelSize;
                double adjustedY = (frameHeight / 2.0 - y) * pixelSize;
                Vector3f translation = new Vector3f((float)adjustedX, (float)adjustedY, 0);
                
                // 在基准位置生成实体，使用translation调整相对位置（与BadApple一致）
                TextDisplay textDisplay = world.spawn(startLocation, TextDisplay.class, td -> {
                    td.setBillboard(Display.Billboard.FIXED);
                    td.setText(" "); // 使用空格，通过背景色显示颜色，与BadApple一致
                    
                    // 使用动态像素大小进行缩放设置
                    float pixelSizeF = (float)pixelSize;
                    float baseScale = pixelSizeF * 4.01f; // 比间距略小，防止像素重叠
                    float visualScaleY = baseScale;
                    float visualScaleX = baseScale * 2.0013f; // 修正横纵比
                    
                    // 根据配置文件中的朝向设置正确的旋转
                    String direction = plugin.getTextDirection();
                    org.joml.Quaternionf rotation = getTextDisplayRotation(direction);
                    
                    // 使用translation调整位置，rotation控制朝向（与BadApple完全一致）
                    td.setTransformation(new Transformation(
                            translation, // 使用translation参数调整位置
                            new AxisAngle4f(rotation), // 使用配置的朝向
                            new Vector3f(visualScaleX, visualScaleY, visualScaleY),
                            new AxisAngle4f(0, 0, 0, 1)
                    ));
                    
                    // 添加标签，便于管理
                    td.addScoreboardTag("tianguo");
                    td.addScoreboardTag("screen");
                    
                    // 其他设置与BadApple保持一致
                    td.setSeeThrough(false);
                    td.setShadowed(false);
                });
                textDisplayUUIDs.add(textDisplay.getUniqueId());
            }
        }
        
        plugin.getLogger().info("已创建 " + textDisplayUUIDs.size() + " 个 TextDisplay 实体 (" + frameWidth + "x" + frameHeight + ")");
        plugin.getLogger().info("新分辨率优化：相比160x90(14400实体)，当前80x45仅需" + textDisplayUUIDs.size() + "个实体，性能提升75%");
    }

    private void createTextDisplayEntities(Location startLocation) {
        createTextDisplayEntities(startLocation, plugin.getPixelSize());
    }

    /**
     * 根据配置的朝向计算 TextDisplay 实体的旋转角度
     * @param direction 朝向配置 (NORTH, SOUTH, EAST, WEST)
     * @return 旋转四元数
     */
    private org.joml.Quaternionf getTextDisplayRotation(String direction) {
        // 基础朝向角度（相对于NORTH方向的偏移）
        float baseYaw = switch (direction.toUpperCase()) {
            case "NORTH" -> 0f;          // 朝北，无偏移
            case "SOUTH" -> 180f;        // 朝南，旋转180度
            case "EAST" -> 270f;         // 朝东，旋转270度（-90度）
            case "WEST" -> 90f;          // 朝西，旋转90度
            default -> 0f;               // 默认朝北
        };
        
        // 正面朝向玩家需要额外旋转180度
        float finalYaw = baseYaw + 180f;
        
        return new org.joml.Quaternionf().rotationYXZ((float) Math.toRadians(finalYaw), 0, 0);
    }

    private void renderFrame(int frameIndex) {
        if (frameIndex >= frames.size()) {
            return;
        }
        List<Color> frame = frames.get(frameIndex);
        
        // 确保实体数量和帧数据匹配
        int totalPixels = this.actualFrameWidth * this.actualFrameHeight;
        if (textDisplayUUIDs.size() != totalPixels || frame.size() != totalPixels) {
            plugin.getLogger().warning("实体数量或帧数据不匹配: 实体=" + textDisplayUUIDs.size() + 
                ", 帧数据=" + frame.size() + ", 预期=" + totalPixels);
            return;
        }
        
        // 为每个像素更新对应的 TextDisplay 实体
        for (int i = 0; i < textDisplayUUIDs.size() && i < frame.size(); i++) {
            UUID uuid = textDisplayUUIDs.get(i);
            Entity entity = Bukkit.getEntity(uuid);
            if (entity instanceof TextDisplay) {
                TextDisplay textDisplay = (TextDisplay) entity;
                textDisplay.setBackgroundColor(frame.get(i));
            }
        }
    }

    private void removeTextDisplayEntities() {
        for (UUID uuid : textDisplayUUIDs) {
            Entity entity = Bukkit.getEntity(uuid);
            if (entity != null) {
                entity.remove();
            }
        }
        textDisplayUUIDs.clear();
    }

    public boolean isPlaying() {
        return isPlaying;
    }
}
